import logging
import pymysql
import log

log.init_log("./log/dealmysql")
class DealMysql:
    '''增对时效性项目电视剧和综艺检测是否更新完成需求，封装了一下pymysql的操作
    '''
    def __init__(self, host, user, password, database, table, port=3306, charset="utf-8"):
        self._host = host
        self._user = user
        self._password = password
        self._database = database
        self._port = port
        self._charset = charset
        self._table = table

    # 类构造函数应该尽量简单，不能包含可能失败或过于复杂的操作。
    # 因此额外添加一个connect函数，记得创建实例后执行一下。
    def connect(self):
        try:
            self.db = pymysql.connect(
                host = self._host,
                user = self._user,
                password = self._password,
                db = self._database,
                port = self._port,
                charset=self._charset)
            self.cur = self.db.cursor()    # 获取操作游标
        except pymysql.Error as e:
            print("连接mysql数据库时发生错误：%s" % e)
            logging.error('连接mysql数据库时发生错误：%s' % e)
            raise e
    
    def use_table(self, table):
        '''更改要操作哪个数据表，不更改的话就默认用初始化实例对象时候设置的。
        
        Args: 传入参数直接就是表名字符串。
        '''
        self._table = table

    def select(self, col_name=None, extra='', table=None):
        '''查询数据

        Args: 
            col_name: 要查询哪些列, 用列表（里面每个元素是列名字符串）形式传入，默认查询所有列。
            extra: 如果有附加查询限定，用字符串形式写入。
            table: 查询哪个数据表。
        
        Returns:
            查询结果
        '''
        # 不设置字段名的话默认查询所有字段
        if not col_name:
            col_name = ['*']
        # 不设置表名的话默认查询之前设置过的表
        if not table:
            table = self._table

        col = ', '.join(col_name)
        sql = 'SELECT %s FROM %s %s;' % (col, table, extra)
        try:
            self.cur.execute(sql)
            results = self.cur.fetchall()
            return results
        except pymysql.Error as e:
            print('查询数据出错：%s' % e)
            logging.warning('查询数据出错：%s' % e)
            raise e
        # finally:
            # self.db.close()

    def insert(self, values, col_name = None, table = None):
        '''向数据库中插入一条数据。
        
        Args: 传入第一个参数为欲添加的条目各个字段的值，第二个参数为数据库中一一对应的字段名，都用列表的方式传入。
            values: 插入的值的组成的列表。
            col_name: 字段名字符串组成的列表，可以不传入，既按照顺序插入值。
            table: 默认用已经选中的表，也可以在这里修改。
        '''
        if not table:
            table = self._table

        values = [str(x) for x in values]
        values = r'", "'.join(values)
        values = r'"' + values + r'"'

        if not col_name:
            sql = 'INSERT INTO %s VALUES (%s);' % (table, values)
        else:
            col = ', '.join(col_name)
            sql = 'INSERT INTO %s (%s) VALUES (%s);' % (table, col, values)

        try:
            self.cur.execute(sql)
            self.db.commit()    # 提交
        except pymysql.Error as e:
            print('向数据库插入数据出错：%s' % e)
            logging.warning('向数据库插入数据出错：%s' % e)
            self.db.rollback()    # 错误回滚

    def update(self, new_data_dict, condition, table = None):
        '''用于更新数据。
        
        Args:
            new_data_dict: 预更新的键值对，key充当字段名，value充当新值。
            condition: 选中某条数据的条件。
            table: 默认用已经选中的表，也可以在这里修改。
        '''
        if not table:
            table = self._table

        data = [key + r'="' + str(new_data_dict[key]) + r'"' for key in new_data_dict]
        data = ', '.join(data)

        condition = [key + r'="' + str(condition[key]) + r'"' for key in condition]
        condition = ', '.join(condition)

        sql = 'UPDATE %s SET %s WHERE %s;' % (table, data, condition)
        try:
            self.cur.execute(sql)
            self.db.commit()
        except pymysql.Error as e:
            print('更新数据库出错：%s' % e)
            logging.warning('更新数据库出错：%s' % e)
            self.db.rollback()
            
    def delete_all(self, table):
        '''用于清空某表数据，但不删除表
        用在监控电视剧和综艺是否更新完成的脚本开始处。
        Args: 
            table: 必须传入表名，防止误删。
        '''
        sql = 'DELETE FROM '+ table
        try:
            self.cur.execute(sql)
            self.db.commit()
        except pymysql.Error as e:
            print('初始清空数据表时出错：%s' % e)
            logging.warning('初始清空数据表时出错：%s' % e)
            self.db.rollback()